//
//  STDSBilateralBlurEffect.h
//  STDSRenderSDKIOS
//
//  Created by 陈学明 on 2023/4/27.
//

#ifndef STDSBilateralBlurEffect_h
#define STDSBilateralBlurEffect_h

#include "STDSBaseEffect.hpp"

/// 马赛克效果
class STDSBilateralBlurEffect: public STDSBaseEffect {
public:
    STDSBilateralBlurEffect() {
        mEffectType = STDSEffectTypeBilateralBlur;
    }
    ~STDSBilateralBlurEffect() {
//        printf("dealloc--STDSMosaicEffect\n");
    }
    
    void setFloatArguments(const char *name, float *floatValue, int n) override {
        if (strcmp("radius", name) == 0) {
            
        } else if (strcmp("threshold", name) == 0) {
            
        }
    }
    
    void setRadius(float radius) {
        mDetailRadius = radius;
    }
    
    void setThreshold(float threshold) {
        mDetailThreshold = threshold;
    }
public:
    shared_ptr<STDSShaderProgram> getEffectProgram() {
        if (mBlurProgram == nullptr) {
            mBlurProgram = mContext->getProgram(kShaderSRCBiLateralBlur);
        }
        return mBlurProgram;
    }
    
    void draw() override {
        auto program = this->getEffectProgram();
        if (program == nullptr) {
            return;
        }
        vec2 uStep(0.125f / mSizeSRC.x * mDetailRadius, 0.125f / mSizeSRC.y * mDetailRadius);
        auto fbo = make_shared<STDSRenderTarget>(mSizeSRC.x, mSizeSRC.y);
        fbo->bindSelf();
        drawTexToCache(mTexture, program, uStep.x, 0.0);
        fbo->restore();
        drawTexToCache(fbo->getTexture(), program, 0.0, uStep.y);
    }
    
    void drawTexToCache(shared_ptr<STDSTexture> _tex, shared_ptr<STDSShaderProgram> program, float _stepX, float _stepY) {
        program->use();
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, _tex->getId());
        program->setUniform(program->getUniform("uTexture"), 0);
        program->setUniform2f(program->getUniform("uStep"), _stepX,_stepY);
        program->setUniform(program->getUniform("uThreshold"), mDetailThreshold * 0.01f);//数值越大 图像越平滑，线条越少 适配AE
        mAtbRect.setPosVex(program->getAttrib("aPos"));
        mAtbRect.setPosTex(program->getAttrib("aTexCoord"));
        mAtbRect.draw();
        program->unuse();
    }

private:
    float mDetailRadius{10.0};
    float mDetailThreshold{40.0};
    shared_ptr<STDSShaderProgram> mBlurProgram{nullptr};
};
#endif /* STDSBilateralBlurEffect_h */
